home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-SPAR.{_A / SYSTEM.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  8KB  |  260 lines

  1. /* $Id: system.h,v 1.48 1999/01/02 16:50:28 davem Exp $ */
  2. #ifndef __SPARC64_SYSTEM_H
  3. #define __SPARC64_SYSTEM_H
  4.  
  5. #include <asm/ptrace.h>
  6. #include <asm/processor.h>
  7. #include <asm/asm_offsets.h>
  8. #include <asm/visasm.h>
  9.  
  10. #ifndef __ASSEMBLY__
  11. /*
  12.  * Sparc (general) CPU types
  13.  */
  14. enum sparc_cpu {
  15.   sun4        = 0x00,
  16.   sun4c       = 0x01,
  17.   sun4m       = 0x02,
  18.   sun4d       = 0x03,
  19.   sun4e       = 0x04,
  20.   sun4u       = 0x05, /* V8 ploos ploos */
  21.   sun_unknown = 0x06,
  22.   ap1000      = 0x07, /* almost a sun4m */
  23. };
  24.                   
  25. #define sparc_cpu_model sun4u
  26.  
  27. /* This cannot ever be a sun4c nor sun4 :) That's just history. */
  28. #define ARCH_SUN4C_SUN4 0
  29. #define ARCH_SUN4 0
  30.  
  31. extern unsigned long empty_bad_page;
  32. extern unsigned long empty_zero_page;
  33. #endif
  34.  
  35. #define setipl(__new_ipl) \
  36.     __asm__ __volatile__("wrpr    %0, %%pil"  : : "r" (__new_ipl) : "memory")
  37.  
  38. #define __cli() \
  39.     __asm__ __volatile__("wrpr    15, %%pil" : : : "memory")
  40.  
  41. #define __sti() \
  42.     __asm__ __volatile__("wrpr    0, %%pil" : : : "memory")
  43.  
  44. #define getipl() \
  45. ({ unsigned long retval; __asm__ __volatile__("rdpr    %%pil, %0" : "=r" (retval)); retval; })
  46.  
  47. #define swap_pil(__new_pil) \
  48. ({    unsigned long retval; \
  49.     __asm__ __volatile__("rdpr    %%pil, %0\n\t" \
  50.                  "wrpr    %1, %%pil" \
  51.                  : "=r" (retval) \
  52.                  : "r" (__new_pil) \
  53.                  : "memory"); \
  54.     retval; \
  55. })
  56.  
  57. #define read_pil_and_cli() \
  58. ({    unsigned long retval; \
  59.     __asm__ __volatile__("rdpr    %%pil, %0\n\t" \
  60.                  "wrpr    15, %%pil" \
  61.                  : "=r" (retval) \
  62.                  : : "memory"); \
  63.     retval; \
  64. })
  65.  
  66. #define __save_flags(flags)    ((flags) = getipl())
  67. #define __save_and_cli(flags)    ((flags) = read_pil_and_cli())
  68. #define __restore_flags(flags)    setipl((flags))
  69.  
  70. #ifndef __SMP__
  71. #define cli() __cli()
  72. #define sti() __sti()
  73. #define save_flags(x) __save_flags(x)
  74. #define restore_flags(x) __restore_flags(x)
  75. #define save_and_cli(x) __save_and_cli(x)
  76. #else
  77.  
  78. #ifndef __ASSEMBLY__
  79. extern void __global_cli(void);
  80. extern void __global_sti(void);
  81. extern unsigned long __global_save_flags(void);
  82. extern void __global_restore_flags(unsigned long flags);
  83. #endif
  84.  
  85. #define cli()            __global_cli()
  86. #define sti()            __global_sti()
  87. #define save_flags(x)        ((x) = __global_save_flags())
  88. #define restore_flags(flags)    __global_restore_flags(flags)
  89. #define save_and_cli(flags)    do { save_flags(flags); cli(); } while(0)
  90.  
  91. #endif
  92.  
  93. #define mb()          __asm__ __volatile__ ("stbar" : : : "memory")
  94.  
  95. #define nop()         __asm__ __volatile__ ("nop")
  96.  
  97. #define membar(type)    __asm__ __volatile__ ("membar " type : : : "memory");
  98. #define rmb()        membar("#LoadLoad | #LoadStore")
  99. #define wmb()        membar("#StoreLoad | #StoreStore")
  100.  
  101. #define flushi(addr)    __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
  102.  
  103. #define flushw_all()    __asm__ __volatile__("flushw")
  104.  
  105. /* Performance counter register access. */
  106. #define read_pcr(__p)  __asm__ __volatile__("rd    %%pcr, %0" : "=r" (__p))
  107. #define write_pcr(__p) __asm__ __volatile__("wr    %0, 0x0, %%pcr" : : "r" (__p));
  108. #define read_pic(__p)  __asm__ __volatile__("rd %%pic, %0" : "=r" (__p))
  109. #define reset_pic()    __asm__ __volatile__("wr    %g0, 0x0, %pic");
  110.  
  111. #ifndef __ASSEMBLY__
  112.  
  113. extern void synchronize_user_stack(void);
  114.  
  115. extern __inline__ void flushw_user(void)
  116. {
  117.     __asm__ __volatile__("
  118.         rdpr        %%otherwin, %%g1
  119.         brz,pt        %%g1, 1f
  120.          mov        %%o7, %%g3
  121.         call        __flushw_user
  122.          clr        %%g2
  123. 1:"    : : : "g1", "g2", "g3");
  124. }
  125.  
  126. #define flush_user_windows flushw_user
  127.  
  128.     /* See what happens when you design the chip correctly?
  129.      *
  130.      * XXX What we are doing here assumes a lot about gcc reload
  131.      * XXX internals, it heavily risks compiler aborts due to
  132.      * XXX forbidden registers being spilled.  Rewrite me...  -DaveM
  133.      *
  134.      * SMP NOTE: At first glance it looks like there is a tiny
  135.      *           race window here at the end.  The possible problem
  136.      *           would be if a tlbcachesync MONDO vector got delivered
  137.      *           to us right before we set the final %g6 thread reg
  138.      *           value.  But that is impossible since only the holder
  139.      *           of scheduler_lock can send a tlbcachesync MONDO and
  140.      *           by definition we hold it right now.  Normal tlb
  141.      *           flush xcalls can come in, but those are safe and do
  142.      *           not reference %g6.
  143.      */
  144. #define switch_to(prev, next)                            \
  145. do {    if (current->tss.flags & SPARC_FLAG_PERFCTR) {                \
  146.         unsigned long __tmp;                        \
  147.         read_pcr(__tmp);                        \
  148.         current->tss.pcr_reg = __tmp;                    \
  149.         read_pic(__tmp);                        \
  150.         current->tss.kernel_cntd0 += (unsigned int)(__tmp);        \
  151.         current->tss.kernel_cntd1 += ((__tmp) >> 32);            \
  152.     }                                    \
  153.     save_and_clear_fpu();                            \
  154.     __asm__ __volatile__(                            \
  155.     "flushw\n\t"                                \
  156.     "wrpr    %g0, 0x94, %pstate\n\t");                    \
  157.     __get_mmu_context(next);                        \
  158.     (next)->mm->cpu_vm_mask |= (1UL << smp_processor_id());            \
  159.     __asm__ __volatile__(                            \
  160.     "wrpr    %%g0, 0x95, %%pstate\n\t"                    \
  161.     "stx    %%l0, [%%sp + 2047 + 0x60]\n\t"                    \
  162.     "stx    %%l1, [%%sp + 2047 + 0x68]\n\t"                    \
  163.     "stx    %%i6, [%%sp + 2047 + 0x70]\n\t"                    \
  164.     "stx    %%i7, [%%sp + 2047 + 0x78]\n\t"                    \
  165.     "rdpr    %%wstate, %%o5\n\t"                        \
  166.     "stx    %%o6, [%%g6 + %2]\n\t"                        \
  167.     "sth    %%o5, [%%g6 + %1]\n\t"                        \
  168.     "rdpr    %%cwp, %%o5\n\t"                        \
  169.     "sth    %%o5, [%%g6 + %4]\n\t"                        \
  170.     "mov    %0, %%g6\n\t"                            \
  171.     "lduh    [%0 + %4], %%g1\n\t"                        \
  172.     "wrpr    %%g1, %%cwp\n\t"                        \
  173.     "ldx    [%%g6 + %2], %%o6\n\t"                        \
  174.     "lduh    [%%g6 + %1], %%o5\n\t"                        \
  175.     "lduh    [%%g6 + %3], %%o7\n\t"                        \
  176.     "mov    %%g6, %%l2\n\t"                            \
  177.     "wrpr    %%o5, 0x0, %%wstate\n\t"                    \
  178.     "ldx    [%%sp + 2047 + 0x60], %%l0\n\t"                    \
  179.     "ldx    [%%sp + 2047 + 0x68], %%l1\n\t"                    \
  180.     "ldx    [%%sp + 2047 + 0x70], %%i6\n\t"                    \
  181.     "ldx    [%%sp + 2047 + 0x78], %%i7\n\t"                    \
  182.     "wrpr    %%g0, 0x94, %%pstate\n\t"                    \
  183.     "mov    %%l2, %%g6\n\t"                            \
  184.     "wrpr    %%g0, 0x96, %%pstate\n\t"                    \
  185.     "andcc    %%o7, 0x100, %%g0\n\t"                        \
  186.     "bne,pn    %%icc, ret_from_syscall\n\t"                    \
  187.     " nop\n\t"                                \
  188.     :                                     \
  189.     : "r" (next),                                \
  190.       "i" ((const unsigned long)(&((struct task_struct *)0)->tss.wstate)),    \
  191.       "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)),    \
  192.       "i" ((const unsigned long)(&((struct task_struct *)0)->tss.flags)),    \
  193.       "i" ((const unsigned long)(&((struct task_struct *)0)->tss.cwp))    \
  194.     : "cc", "g1", "g2", "g3", "g5", "g7",                    \
  195.       "l2", "l3", "l4", "l5", "l6", "l7",                    \
  196.       "i0", "i1", "i2", "i3", "i4", "i5",                    \
  197.       "o0", "o1", "o2", "o3", "o4", "o5", "o7");                \
  198.     /* If you fuck with this, update ret_from_syscall code too. */        \
  199.     if (current->tss.flags & SPARC_FLAG_PERFCTR) {                \
  200.         write_pcr(current->tss.pcr_reg);                \
  201.         reset_pic();                            \
  202.     }                                    \
  203. } while(0)
  204.  
  205. extern __inline__ unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
  206. {
  207.     __asm__ __volatile__("
  208.     mov        %0, %%g5
  209. 1:    lduw        [%2], %%g7
  210.     cas        [%2], %%g7, %0
  211.     cmp        %%g7, %0
  212.     bne,a,pn    %%icc, 1b
  213.      mov        %%g5, %0
  214.     membar        #StoreLoad | #StoreStore
  215. "    : "=&r" (val)
  216.     : "0" (val), "r" (m)
  217.     : "g5", "g7", "cc", "memory");
  218.     return val;
  219. }
  220.  
  221. extern __inline__ unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
  222. {
  223.     __asm__ __volatile__("
  224.     mov        %0, %%g5
  225. 1:    ldx        [%2], %%g7
  226.     casx        [%2], %%g7, %0
  227.     cmp        %%g7, %0
  228.     bne,a,pn    %%xcc, 1b
  229.      mov        %%g5, %0
  230.     membar        #StoreLoad | #StoreStore
  231. "    : "=&r" (val)
  232.     : "0" (val), "r" (m)
  233.     : "g5", "g7", "cc", "memory");
  234.     return val;
  235. }
  236.  
  237. #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  238. #define tas(ptr) (xchg((ptr),1))
  239.  
  240. extern void __xchg_called_with_bad_pointer(void);
  241.  
  242. static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
  243.                        int size)
  244. {
  245.     switch (size) {
  246.     case 4:
  247.         return xchg32(ptr, x);
  248.     case 8:
  249.         return xchg64(ptr, x);
  250.     };
  251.     __xchg_called_with_bad_pointer();
  252.     return x;
  253. }
  254.  
  255. extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
  256.  
  257. #endif /* !(__ASSEMBLY__) */
  258.  
  259. #endif /* !(__SPARC64_SYSTEM_H) */
  260.